# Dataframe
# 分组 、聚合
import pandas as pd

df=pd.DataFrame({'班级':['一班','二班','二班','一班','二班','二班'],"语文":[28,63,16,45,37,48],
                 "数学":[28,63,87,55,22,98]},index=['张三','李四','王五','赵六','哈利波特','艾克'])
print(df)
print()
#分组(列名)
print(df.groupby('班级')) #按照班级分组，分组结果是一个对象
print()
#查看分组结果：遍历
for i in df.groupby('班级'):
    print(i)

#元组(组名，该组所有的行组成的Dataframe)
#从分组中单独取出一个组的数据
print([x for x in df.groupby('班级')]) #由元组构成的列表
print()
print(dict([x for x in df.groupby('班级')])) # 将元组变成字典，{组名: 该组所有的行组成的Datafarme}
print()
print(dict([x for x in df.groupby('班级')])['二班']) # 使用键获取单独的分组

#分组(Series指定分组)

#分组(字典指定分组)

#分组(按函数的值)
for i in df.groupby(len):
    print(i)

#聚合
print(df.groupby('班级').mean())
print(df.groupby('班级')['语文'].mean())
print(df.groupby('班级').语文.mean())

#agg()聚合
def range_of_group(a): #极差
    return a.max()-a.min()

print(df.groupby('班级').语文.agg(range_of_group)) # 自定义函数要通过agg()应用
print(df.groupby('班级').agg([range_of_group,'mean'])) # 同时计算多个统计量
print(df.groupby('班级').agg([('极差',range_of_group),('平均数','mean')])) # 同时计算多个统计量并计算
print(df.groupby('班级').agg({'语文':range_of_group,'数学':'sum'})) #不同列计算不同统计量

#transform()聚合
print(df.groupby('班级').语文.transform(range_of_group))

#apply（）数据变形
def plus_ten(a):
    return a.iloc[:,:1]+10


print(df.groupby('班级').apply(plus_ten))

data=pd.read_excel('3/2020年销售数据.xlsx')
print(data.head())
#数据透视表
print(pd.pivot_table(data,index='销售区域',values='销售数量',aggfunc='sum'))
print(pd.pivot_table(data,index=['销售区域',data['销售日期'].dt.month],values='销售数量',aggfunc='sum'))
#数据交叉表（把二层索引展开为横竖两部分）
print(pd.pivot_table(data,index='销售区域',columns=data['销售日期'].dt.month,values='销售数量',aggfunc='sum',fill_value=0)) # 每个区域每个月的销售数量总和

data['月']=data['销售日期'].dt.month
print(pd.pivot_table(data,index='销售区域',columns='月',values='销售数量',aggfunc='sum',fill_value=0,margins=True,margins_name='小计')) # 增加小计

print(pd.crosstab(index=data['销售区域'],values=data['销售数量'],columns=data['月'],aggfunc='sum').fillna(0))
